package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import com.atguigu.tingshu.album.AlbumFeignClient;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.alibaba.nacos.common.utils.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

	@Autowired
	private TrackInfoMapper trackInfoMapper;
    @Autowired
    private AlbumInfoMapper albumInfoMapper;
    @Autowired
    private VodService vodService ;
    @Autowired
    private TrackStatMapper trackStatMapper;

    @Autowired
    private AlbumFeignClient albumFeignClient;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private AlbumStatMapper albumStatMapper;

    /**
     * 根据声音ID+声音数量 获取下单付费声音列表
     * /api/album/trackInfo/findPaidTrackInfoList/{trackId}/{trackCount}
     * @param trackId
     * @param trackCount
     * @return
     */
    @Override
    public List<TrackInfo> findPaidTrackInfoList(Long trackId, Integer trackCount,Long userId) {
        //获取单个声音信息
        TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
        //获取用户已经购买过的
        List<Long> userPaidTrackList = userFeignClient.findUserPaidTrackList(trackInfo.getAlbumId()).getData();
        //获取这个声音信息后面的多个
        LambdaQueryWrapper<TrackInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TrackInfo::getAlbumId,trackInfo.getAlbumId());
        lambdaQueryWrapper.ge(TrackInfo::getOrderNum,trackInfo.getOrderNum());
        if (userPaidTrackList!=null){
            lambdaQueryWrapper.notIn(TrackInfo::getId,userPaidTrackList);
        }
        lambdaQueryWrapper.last(" limit " + trackCount);

        List<TrackInfo> list = trackInfoMapper.selectList(lambdaQueryWrapper);

        return list;
    }


    /**
     * 获取用户声音分集购买支付列表
     * /api/album/trackInfo/findUserTrackPaidList/{trackId}
     * @return
     */
    @Override
    public List<Map<String, Object>> findUserTrackPaidList(Long trackId, Long userId) {
        //返回结果封装
        List mapList = new ArrayList();
        //查询单个声音列表
        TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
        //根据专辑id查询声音价格
        AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
        //声音价格
        BigDecimal price = albumInfo.getPrice();
        //根据单个声音信息获取该声音以后的所有信息同时排除已经购买过的
        QueryWrapper<TrackInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("album_id",trackInfo.getAlbumId());
        queryWrapper.ge("order_num",trackInfo.getOrderNum());
        List<TrackInfo> trackInfoList = trackInfoMapper.selectList(queryWrapper);
        if (CollectionUtil.isEmpty(trackInfoList)){
            throw new GuiguException(400,"该专辑下没有可购买的声音");
        }
        if (userId!=null){
            //查询这个用户是否购买过这本专辑的声音
            List<Long> trackIdList = userFeignClient.findUserPaidTrackList(trackInfo.getAlbumId()).getData();
            if (!CollectionUtil.isEmpty(trackIdList)){
                //不是空会进入
                trackInfoList= trackInfoList.stream().filter(trackInfo1 -> !trackIdList.contains(trackInfo1.getId())).collect(Collectors.toList());
            }
        }
        //@TODO
        Map<String, Object> map1 = new HashMap<>();
        map1.put("name", "购买1"+ "集");
        map1.put("price", price);
        map1.put("trackCount", 1);
        mapList.add(map1);
        //到这里trackInfoList就是要购买的声音
        for (int i = 10; i < 50; i+=10) {
            if (i<trackInfoList.size()){
                Map<String, Object> map = new HashMap<>();
                map.put("name", "后" + i + "集");
                map.put("price", price.multiply(new BigDecimal(i)));
                map.put("trackCount", i);
                mapList.add(map);
            }else {
                Map<String, Object> map = new HashMap<>();
                map.put("name", "后" + trackInfoList.size() + "集");
                map.put("price", price.multiply(new BigDecimal(trackInfoList.size())));
                map.put("trackCount", trackInfoList.size());
                mapList.add(map);
                break;
            }
        }
        return mapList;
    }



    /**
     * 获取声音统计信息
     * /api/album/trackInfo/getTrackStatVo/{trackId}
     */
    @Override
    public TrackStatVo getTrackStatVo(Long trackId) {
        TrackStatVo trackStatVo = trackStatMapper.gselectTrackStatVo(trackId);
        return trackStatVo;
    }


    /**
     * 声音专辑统计
     * @param trackStatMqVo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateTrackStat(TrackStatMqVo trackStatMqVo) {
        //唯一标识
        String key = "businessNo" +trackStatMqVo.getBusinessNo();
        //判断是否是重复数据，如果不存在返回true
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(key, trackStatMqVo.getBusinessNo(), 1, TimeUnit.HOURS);
        //判断
        if (!aBoolean){
            //表示已经存入直接返回
            return;
        }
        //更新声音统计
        trackStatMapper.updateTrackStat(trackStatMqVo);
        //更新专辑统计
        if (trackStatMqVo.getStatType().equals(SystemConstant.TRACK_STAT_PLAY)){
            albumStatMapper.updateTrackStat(trackStatMqVo,SystemConstant.ALBUM_STAT_PLAY);
        }
        if(trackStatMqVo.getStatType().equals(SystemConstant.TRACK_STAT_COMMENT)){
            albumStatMapper.updateTrackStat(trackStatMqVo,SystemConstant.ALBUM_STAT_COMMENT);
        }
    }



    /**
     * 查询专辑声音分页列表
     * /api/album/trackInfo/findAlbumTrackPage/{albumId}/{page}/{limit}
     */
    @Override
    public Page<AlbumTrackListVo> findAlbumTrackPage(Long albumId, Page<AlbumTrackListVo> page1,Long userId) {
        Page<AlbumTrackListVo> albumTrackListVoPage = trackInfoMapper.findAlbumTrackPage(albumId,page1);
        //获取专辑类型，免费 ，vip免费，付费
        AlbumInfo albumInfo = albumFeignClient.getAlbumInfo(albumId).getData();
        Assert.notNull(albumInfo,"专辑查询ID：{}，出现异常",albumId);
        String payType = albumInfo.getPayType();

        //判断用户是否登录
        if (userId==null){
            //没有登录
            if (payType.equals(SystemConstant.ALBUM_PAY_TYPE_VIPFREE) || payType.equals(SystemConstant.ORDER_ITEM_TYPE_VIP)){
                //进入这里说明不是免费的，除了试听的都要付费
                albumTrackListVoPage.getRecords().stream().filter(new Predicate<AlbumTrackListVo>() {
                    @Override
                    public boolean test(AlbumTrackListVo albumTrackListVo) {
                        return albumTrackListVo.getOrderNum() > albumInfo.getTracksForFree();
                    }
                }).forEach(albumTrackListVo -> {
                    albumTrackListVo.setIsShowPaidMark(true);
                });
            }
        }else{
            //登录
            //设置变量
            Boolean isNeedCheckPayStatus = false;
            //获取用户vip信息
            UserInfoVo userInfoVo = userFeignClient.getUserInfoVo(userId).getData();
            Integer isVip = userInfoVo.getIsVip();
            //VIP的到期时间
            Date vipExpireTime = userInfoVo.getVipExpireTime();
            //vip免费判断
            if (payType.equals(SystemConstant.ALBUM_PAY_TYPE_VIPFREE)){
                if (isVip.intValue()==0){
                    isNeedCheckPayStatus = true;
                }
                if (isVip.intValue()==1&&new Date().after(vipExpireTime)){
                    isNeedCheckPayStatus = true;
                }
            }
            //付费免费判断
            if (payType.equals(SystemConstant.ALBUM_PAY_TYPE_REQUIRE)){
                isNeedCheckPayStatus = true;
            }

            if (isNeedCheckPayStatus){
                List<AlbumTrackListVo> collect = albumTrackListVoPage.getRecords().stream().filter(new Predicate<AlbumTrackListVo>() {
                    @Override
                    public boolean test(AlbumTrackListVo albumTrackListVo) {
                        return albumTrackListVo.getOrderNum() > albumInfo.getTracksForFree();
                    }
                }).collect(Collectors.toList());
                //只有id的集合
                List<Long> collect1 = collect.stream().map(albumTrackListVo -> albumTrackListVo.getTrackId()).collect(Collectors.toList());
                //查看付费情况
                Map<Long, Integer> data = userFeignClient.userIsPaidTrack(userId, albumId, collect1).getData();

                for (AlbumTrackListVo albumTrackListVo : collect) {
                    Integer integer = data.get(albumTrackListVo.getTrackId());
                    if (integer.intValue()==0){
                        albumTrackListVo.setIsShowPaidMark(true);
                    }
                }
            }
        }
        return albumTrackListVoPage;
    }



    /**
     * 保存声音
     * /api/album/trackInfo/saveTrackInfo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveTrackInfo(TrackInfoVo trackInfoVo, Long userId) {
        //拷贝数据
        TrackInfo trackInfo = BeanUtil.copyProperties(trackInfoVo, TrackInfo.class);
        trackInfo.setUserId(userId);
        //根据当前声音所属专辑id查询专辑信息
        AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
        //设置专辑包含声音总数+1
        albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount()+1);
        //查询云点播声音的 时长 ，大小，类型
        TrackMediaInfoVo trackMediaInfoVo = vodService.getTrackMediaInfo(trackInfo.getMediaFileId());
        trackInfo.setMediaDuration(new BigDecimal(trackMediaInfoVo.getDuration()));
        trackInfo.setMediaSize(trackMediaInfoVo.getSize());
        trackInfo.setMediaType(trackMediaInfoVo.getType());
        //设置声音来源
        trackInfo.setSource(SystemConstant.TRACK_SOURCE_USER);
        //设置状态
        trackInfo.setStatus(SystemConstant.TRACK_STATUS_PASS);
        //保存声音
        trackInfoMapper.insert(trackInfo);
        //更新专辑包含总数
        albumInfoMapper.updateById(albumInfo);
        //初始化统计信息
        this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_PLAY,0);
        this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_COLLECT,0);
        this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_PRAISE,0);
        this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_COMMENT,0);
    }

    /**
     * 初始化统计信息
     * @param id
     * @param trackStatPraise
     * @param i
     */
    @Override
    public void saveTrackStat(Long id, String trackStatPraise, int i) {
        TrackStat trackStat = new TrackStat();
        trackStat.setTrackId(id);
        trackStat.setStatType(trackStatPraise);
        trackStat.setStatNum(i);
        trackStatMapper.insert(trackStat);
    }

    /**
     * 获取当前用户声音分页列表
     * /api/album/trackInfo/findUserTrackPage/{page}/{limit}
     */
    @Override
    public Page<TrackListVo> findUserTrackPage(Page<TrackListVo> page1, TrackInfoQuery trackInfoQuery) {
        return trackInfoMapper.selectUserTrackPage(page1,trackInfoQuery);
    }

    /**
     *修改声音信息
     * api/album/trackInfo/updateTrackInfo/{id}
     */
    @Override
    public void updateTrackInfo(Long id, TrackInfoVo trackInfoVo) {
        //根据id查询数据信息
        TrackInfo trackInfo = trackInfoMapper.selectById(id);
        //获取修改前的声音id
        String mediaFileId = trackInfo.getMediaFileId();
        //获取修改后的声音id
        String mediaFileId1 = trackInfoVo.getMediaFileId();
        //整合修改数据
        BeanUtils.copyProperties(trackInfoVo,trackInfo);
        //判断是否修改了声音
        if (!StringUtils.equals(mediaFileId, mediaFileId1)){
            vodService.deleteTrackMedia(mediaFileId);
            if (StringUtils.isNotBlank(mediaFileId1)) {
                //查询云点播声音的 时长 ，大小，类型
                TrackMediaInfoVo trackMediaInfo = vodService.getTrackMediaInfo(mediaFileId1);
                trackInfo.setMediaType(trackMediaInfo.getType());
                trackInfo.setMediaDuration(new BigDecimal(trackMediaInfo.getDuration()));
                trackInfo.setMediaSize(trackMediaInfo.getSize());
            }
        }
        //修改
        trackInfoMapper.updateById(trackInfo);
    }

    /**
     * 删除声音信息
     * /api/album/trackInfo/removeTrackInfo/{id}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeTrackInfo(long id) {
        //查询根据声音id，查询声音信息--获取专辑ID
        TrackInfo trackInfo = trackInfoMapper.selectById(id);
        Long albumId = trackInfo.getAlbumId();
        Integer orderNum = trackInfo.getOrderNum();
        //删除声音
        trackInfoMapper.deleteById(id);
        //更新声音排序
        trackInfoMapper.updateOrderNum(albumId,orderNum);
        //根据专辑ID获取专辑对象
        AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
        //更新专辑包含总数
        albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount()-1);
        albumInfo.setUpdateTime(new Date());
        albumInfoMapper.updateById(albumInfo);
        //删除声音统计信息
        trackStatMapper.delete(new QueryWrapper<TrackStat>().eq("track_id",id));
        //云点播声音信息删除
        vodService.deleteTrackMedia(trackInfo.getMediaFileId());
    }


}
